<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>类的基本知识</title>
</head>

<body>
  <script>

    /*
        总结：
          1.类中的构造器不是必须写的，要对实例进行一些初始化的操作，如添加指定属性时才写。
          2.如果A类继承了B类，且A类中写了构造器，那么A类构造器中的super是必须要调用的。
          3.类中定义的方法，都是放在原型上的，供实例使用
    */


    // 创建一个Person类
    class Person {
      // 构造器方法
      constructor(name, age) {
        // 构造器中的this是谁？——> 类的实例对象
        this.name = name;
        this.age = age;
      }
      // 一般方法
      speak() {
        // speack放在哪里？ ——> 类的原型对象上，供实例使用
        // 通过Person实例调用speak时，speak中的this就是Person实例
        console.log(`我叫${this.name}，我的年龄是${this.age}`)
      }
    }
    // 创建一个Person的实例对象
    // const p1 = new Person('张三', 18)
    // const p2 = new Person('李四', 20)
    // console.log('p1: ', p1);
    // console.log('p2: ', p2);
    // p1.speak()
    // p2.speak()


    // 创建一个Student类，继承Person类
    class Student extends Person {
      constructor(name, age, grade) {
        super(name, age)
        this.grade = grade
      }
      // 重写从父类继承过来的方法
      speak() {
        console.log(`我叫${this.name}，我的年龄是${this.age}，我正在读${this.grade}年纪`)
      }
    }
    const s1 = new Student('小张', 15, '初三')
    console.log('s1: ', s1);
    s1.speak()


    class Car {
      constructor(name, price) {
        this.name = name;
        this.price = price;
        // this.wheel = 4;
      }
      // 类中可以直接写赋值语句，如下代码的含义是：给Car的实例对象添加一个属性，名为a,值为4
      a = 4
      wheel = 6
    }
    const c1 = new Car('奔驰', 199)
    const c2 = new Car('宝马', 399)
    console.log(c1)
    console.log(c2)
  </script>
</body>

</html>